class Observer {
  constructor(data) {
    // 将数据对象中的所有key递归地变成响应式数据
    this.toReactive(data);
  }

  // 遍历 data($data)中的属性，把属性转换成响应式数据
  toReactive(data) {
    // data必须为一个对象（递归终止条件）
    if (!data || typeof data !== "object") {
      return;
    }

    /* 将app.$data中的每个key都定义为响应式数据 */
    Object.keys(data).forEach((key) => {
      this.defineReactive(data, key, data[key]);
    });
  }

  // 定义响应式数据
  defineReactive(data, key, value) {
    const that = this;

    // 为当前的响应式属性建立一个依赖对象
    // 负责收集依赖并发送通知
    let dep = new Dep();

    /* 如果通过app.$data去读写数据 */
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,

      // console.log(vue.$data.count)
      get() {
        console.log("ob/get", key);
        // 收集依赖:添加响应式数据count的订阅者
        // 一只看门狗加入了响应式数据count的粉丝团
        Dep.target && dep.addSub(Dep.target);
        
        return value;
      },

      // vue.$data.count = 5
      set(newValue) {
        console.log("ob/set", data, key, newValue);
        if (value === newValue) {
          return;
        }

        // 更新当前数据闭包中的value
        value = newValue;

        // 如果新设置的值为对象，也转换成响应式数据
        that.toReactive(newValue);

        // 发送通知
        dep.notify();
      },
    });

    // 利用递归使深层（内部）属性转换成响应式数据
    this.toReactive(value);
  }
}
